#include <pthread.h>
#include <libspe2.h>
#include <errno.h>
#include <Scheduler.h>
#include <communicator.h>
#include <shared_data.h>
#include <ProcessComposition.h>
#include <Queue.h>
#include <csp_debug.h>
#include <ChannelLog.h>


using namespace std;

/* The SPU-kernel image */
extern spe_program_handle_t kernel;

/* Thread for each communicator. */
pthread_t comm_threads[NUMTHREADS];

ea_addr_t shared_data;

void set_shared_address(void *addr){
	shared_data = (ea_addr_t) addr;
}


void *start_communicator_thread(void *arg){ // {{{
	int i;
	i = ((int) (long) arg);
	spe_communicator(i+1, &kernel);
	pthread_exit(NULL);
} // }}}

/* Start communicator-thread for each SPE. Load kernels. */ 
void CellCSP_start(CSPConfig &conf){ // {{{
	int i;
	extern CSPConfig* configuration; /* shared */

	configuration = &conf;
	


	for(i = 0; i < NUMTHREADS; i++){
		if(pthread_create(&comm_threads[i], NULL, &start_communicator_thread, (void *) i)){
			perror("Communicator-thread was not started");
		}	
	}

} // }}}

/* Wait for all communicator threads to complete. */
int CellCSP_end(){ // {{{
	int i;
	Scheduler &scheduler = *Scheduler::Instance();
	scheduler.StopWhenEmpty();
	for(i = 0; i < NUMTHREADS; i++){
		pthread_join(comm_threads[i], NULL);
	}

	//ChannelLog *channelLog = ChannelLog::Instance();	
	//channelLog->Print();

	return 0;
} // }}}


